package com.mc.cloud.mall.cartOrder.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.zxing.WriterException;
import com.google.zxing.qrcode.encoder.QRCode;
import com.mc.cloud.mall.cartOrder.common.OrderCodeFactory;
import com.mc.cloud.mall.cartOrder.feign.ProductFeignClient;
import com.mc.cloud.mall.cartOrder.feign.UserFeignClient;
import com.mc.cloud.mall.cartOrder.model.mapper.CartMapper;
import com.mc.cloud.mall.cartOrder.model.mapper.OrderItemMapper;
import com.mc.cloud.mall.cartOrder.model.mapper.OrderMapper;
import com.mc.cloud.mall.cartOrder.model.pojo.Order;
import com.mc.cloud.mall.cartOrder.model.pojo.OrderItem;
import com.mc.cloud.mall.cartOrder.model.vo.CartVO;
import com.mc.cloud.mall.cartOrder.model.vo.CreateOrder;
import com.mc.cloud.mall.cartOrder.model.vo.OrderItemVO;
import com.mc.cloud.mall.cartOrder.model.vo.OrderVO;
import com.mc.cloud.mall.categoryProduct.common.ProductConstant;
import com.mc.cloud.mall.categoryProduct.model.mapper.ProductMapper;
import com.mc.cloud.mall.categoryProduct.model.pojo.Product;
import com.mc.cloud.mall.common.common.Constant;
import com.mc.cloud.mall.common.exception.MallException;
import com.mc.cloud.mall.common.exception.MallExceptionEnum;
import com.mc.cloud.mall.common.utils.QRCodeGenerator;
import com.mc.cloud.mall.user.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @ClassName OrderServiceImpl
 * @Author MC
 * @Date 2020/11/9 12:27
 * @Version 1.0
 **/
@Service
public class OrderServiceImpl implements OrderService {
    
    @Autowired
    CartService cartService;
    
    @Autowired
    ProductFeignClient productFeignClient;
    @Autowired
    CartMapper cartMapper;
    
    @Autowired
    OrderMapper orderMapper;
    
    @Autowired
    OrderItemMapper orderItemMapper;
    
    @Autowired
    UserFeignClient userFeignClient;
    
    @Value("${file.upload.ip}")
    String ip;
    
    @Value("${file.upload.port}")
    String port;
    
    @Value("${file.upload.dir}")
    String FILE_UPLOAD_DIR;
    
    //数据库事务
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String create(CreateOrder createOrder){
        //拿到用户id
        Integer userId = userFeignClient.getUser().getId();
        //从用户购物车中选择已经勾选的商品
        List<CartVO> cartVOList = cartService.cartList(userId);
        ArrayList<CartVO> cartVOTemp = new ArrayList<>();
        for (CartVO cartVO : cartVOList) {
            if (cartVO.getSelected().equals(Constant.Cart.CHECKED)) {
                cartVOTemp.add(cartVO);
            }
        }
        cartVOList = cartVOTemp;
        //如果为空，报错
        if (CollectionUtils.isEmpty(cartVOList)){
            throw new MallException(MallExceptionEnum.CART_EMPTY);
        }
        //判断库存 ， 是否上架 ，是否存在
        validSaleStatusAndStock(cartVOList);
        //将购物车对象转换成order对象
        List<OrderItem> orderItemList = cartVOListToOrderItemList(cartVOList);
        //扣库存
        for (OrderItem orderItem : orderItemList) {
            Product product = productFeignClient.productDetailForFeign(orderItem.getProductId());
            int stock = product.getStock() - orderItem.getQuantity();
            if (stock < 0){
                throw new MallException(MallExceptionEnum.NOT_ENOUGH);
            }
            product.setStock(stock);
            productFeignClient.updateProductForFeign(product.getId(),stock);
        }
        //把购物车中勾选的商品删除
        cleanCart(cartVOList);
        //生成订单
        Order order = new Order();
        //生成订单号
        String orderNo = OrderCodeFactory.getOrderCode(Long.valueOf(userId));
        order.setOrderNo(orderNo);
        order.setUserId(userId);
        order.setTotalPrice(orderTotalPrice(orderItemList));
        order.setOrderStatus(Constant.OrderStatusEnum.NOT_PAID.getCode());
        order.setPaymentType(1);
        order.setPostage(0);
        order.setReceiverAddress(createOrder.getReceiverAddress());
        order.setReceiverName(createOrder.getReceiverName());
        order.setReceiverMobile(createOrder.getReceiverMobile());
        //插入到order表中
        orderMapper.insertSelective(order);
        //生成order_item对象
        for (OrderItem orderItem : orderItemList) {
            orderItem.setOrderNo(order.getOrderNo());
            orderItemMapper.insertSelective(orderItem);
        }
        //返回
        return orderNo;
    }
    
    private Integer orderTotalPrice(List<OrderItem> orderItemList) {
        Integer totalPrice = 0;
        for (OrderItem orderItem : orderItemList) {
            totalPrice += orderItem.getTotalPrice();
        }
        return totalPrice;
    }
    
    private void cleanCart(List<CartVO> cartVOList) {
        for (CartVO cartVO : cartVOList) {
            //cartVO.getId()就是购物车的id
            cartMapper.deleteByPrimaryKey(cartVO.getId());
        }
    }
    
    private List<OrderItem> cartVOListToOrderItemList(List<CartVO> cartVOList) {
        
        ArrayList<OrderItem> orderItemList = new ArrayList<>();
        for (CartVO cartVO : cartVOList) {
            OrderItem orderItem = new OrderItem();
            orderItem.setProductId(cartVO.getProductId());
            orderItem.setProductName(cartVO.getProductName());
            orderItem.setProductImg(cartVO.getProductImage());
            orderItem.setQuantity(cartVO.getQuantity());
            orderItem.setTotalPrice(cartVO.getTotalPrice());
            orderItem.setUnitPrice(cartVO.getPrice());
            orderItemList.add(orderItem);
        }
        return orderItemList;
    
    }
    
    private void validSaleStatusAndStock(List<CartVO> cartVOList) {
        for (CartVO cartVO : cartVOList) {
            //查询出商品
            Product product = productFeignClient.productDetailForFeign(cartVO.getProductId());
            //看商品是否存在，以及是否上架
            if (product==null && product.getStatus().equals(Constant.SellStatus.NOT_SALE)){
                throw new MallException(MallExceptionEnum.NOT_SALE);
            }
            //是否超出库存
            if (product.getStock()<cartVO.getQuantity()){
                throw new MallException(MallExceptionEnum.NOT_ENOUGH);
            }
        }
    }
    
    
    @Override
    public OrderVO detail(String orderNo){
        //查询订单是否存在
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order==null){
            throw new MallException(MallExceptionEnum.NO_ORDER);
        }
        //存在是否是本人的
        if (!userFeignClient.getUser().getId().equals(order.getUserId())) {
            throw new MallException(MallExceptionEnum.NOY_YOUR_ORDER);
        }
        OrderVO orderVO = getOrderVo(order);
        return orderVO;
    }
    
    public OrderVO getOrderVo(Order order) {
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(order,orderVO);
        //获取订单对应的orderItemVolist
        //先获取订单对应的orderItemList,在转换
        List<OrderItem> orderItemList = orderItemMapper.selectByOrderNo(order.getOrderNo());
        ArrayList<OrderItemVO> orderItemVOList = new ArrayList<>();
        for (OrderItem orderItem : orderItemList) {
            OrderItemVO orderItemVO = new OrderItemVO();
            BeanUtils.copyProperties(orderItem,orderItemVO);
            orderItemVOList.add(orderItemVO);
        }
        orderVO.setOrderItemVOList(orderItemVOList);
        orderVO.setOrderStatusName(Constant.OrderStatusEnum.codeOf(orderVO.getOrderStatus()).getValue());
        return orderVO;
    }
    
    
    @Override
    public PageInfo orderListForCustom(Integer pageNum, Integer pageSize){
        //查询当前用户的所有订单
        Integer userId = userFeignClient.getUser().getId();
        PageHelper.startPage(pageNum,pageSize);
        List<Order> orderList = orderMapper.selectByUserId(userId);
        //将orderList转换成orderVOList
        List<OrderVO> orderVOList = orderListToOrderVoList(orderList);
        PageInfo pageInfo = new PageInfo<>(orderList);
        pageInfo.setList(orderVOList);
        return pageInfo;
    }
    
    private List<OrderVO> orderListToOrderVoList(List<Order> orderList) {
        ArrayList<OrderVO> orderVOList = new ArrayList<>();
        for (Order order : orderList) {
            OrderVO orderVo = this.getOrderVo(order);
            orderVOList.add(orderVo);
        }
        return orderVOList;
    }
    
    @Override
    public void cancel(String orderNo){
        //查询订单是否存在
        //是否是你自己的
        //查询订单是否存在
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order==null){
            throw new MallException(MallExceptionEnum.NO_ORDER);
        }
        //存在是否是本人的
        if (!userFeignClient.getUser().getId().equals(order.getUserId())) {
            throw new MallException(MallExceptionEnum.NOY_YOUR_ORDER);
        }
        if (order.getOrderStatus().equals(Constant.OrderStatusEnum.NOT_PAID.getCode())){
            order.setOrderStatus(Constant.OrderStatusEnum.CANCELED.getCode());
            order.setEndTime(new Date());
            orderMapper.updateByPrimaryKeySelective(order);
        }else{
            throw new MallException(MallExceptionEnum.WRONG_PRDER_STATUS);
        }
        
    }
    
    @Override
    public String qrcode(String orderNo){
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String address = ip + ":"+ port;
        String payUrl = "http://" + address + "/cartOrder/pay?orderNo=" + orderNo;
        try {
            QRCodeGenerator.generateQRCodeImage(payUrl,350,350, FILE_UPLOAD_DIR+orderNo+".png");
        } catch (WriterException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String pngAddress = "http://" + address + "/cartOrder/images/" +orderNo + ".png";
        return pngAddress;
    }
    
    
    @Override
    public PageInfo orderListForAdmin(Integer pageNum, Integer pageSize){

        PageHelper.startPage(pageNum,pageSize);
        List<Order> orderList = orderMapper.selectAllForAdmin();
        //将orderList转换成orderVOList
        List<OrderVO> orderVOList = orderListToOrderVoList(orderList);
        PageInfo pageInfo = new PageInfo<>(orderList);
        pageInfo.setList(orderVOList);
        
        return pageInfo;
    }
    
    @Override
    public void pay(String orderNo){
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order==null){
            throw new MallException(MallExceptionEnum.NO_ORDER);
        }
        //判断是否是未付款状态
        if (order.getOrderStatus() == Constant.OrderStatusEnum.NOT_PAID.getCode()){
            order.setOrderStatus(Constant.OrderStatusEnum.PAID.getCode());
            order.setPayTime(new Date());
            orderMapper.updateByPrimaryKeySelective(order);
        }else{
            throw new MallException(MallExceptionEnum.WRONG_PRDER_STATUS);
        }
    }
    
    @Override
    public void delivered(String orderNo){
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order==null){
            throw new MallException(MallExceptionEnum.NO_ORDER);
        }
        //判断是否是付款状态
        if (order.getOrderStatus() == Constant.OrderStatusEnum.PAID.getCode()){
            order.setOrderStatus(Constant.OrderStatusEnum.DELIVERED.getCode());
            order.setDeliveryTime(new Date());
            orderMapper.updateByPrimaryKeySelective(order);
        }else{
            throw new MallException(MallExceptionEnum.WRONG_PRDER_STATUS);
        }
    }
    
    @Override
    public void finish(String orderNo){
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order==null){
            throw new MallException(MallExceptionEnum.NO_ORDER);
        }
        
        if (userFeignClient.getUser().getRole().equals(1)&&!order.getUserId().equals(userFeignClient.getUser().getId())) {
            throw new MallException(MallExceptionEnum.NOY_YOUR_ORDER);
        }
        
        //完结
        if (order.getOrderStatus() == Constant.OrderStatusEnum.DELIVERED.getCode()){
            order.setOrderStatus(Constant.OrderStatusEnum.FINISHED.getCode());
            order.setEndTime(new Date());
            orderMapper.updateByPrimaryKeySelective(order);
        }else{
            throw new MallException(MallExceptionEnum.WRONG_PRDER_STATUS);
        }
    }
}
